package com.wz.common.config;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.support.http.StatViewServlet;
import com.alibaba.druid.support.http.WebStatFilter;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.sql.DataSource;
import java.sql.SQLException;
import java.util.Properties;

/**
 * <p>Project: wz_api - DruidDataSourceConfig
 * <p>Powered by pisces On 2022-01-13 14:53:52
 * <P>Created by IntelliJ IDEA
 *
 * @author ww606851@163.com
 * @version 1.0
 * @description:
 * @since 8
 */

@Configuration
@ConfigurationProperties(prefix = "spring.datasource")
@Data
public class DruidDataSourceConfig {
    private String url;
    private String username;
    private String password;
    private String driverClassName;
    private int initialSize;
    private int minIdle;
    private int maxActive;
    private int maxWait;
    private int timeBetweenEvictionRunsMillis;
    private int minEvictableIdleTimeMillis;
    private String validationQuery;
    private boolean testWhileIdle;
    private boolean testOnBorrow;
    private boolean testOnReturn;
    private boolean poolPreparedStatements;
    private int maxPoolPreparedStatementPerConnectionSize;
    private int connectionErrorRetryAttempts;
    private boolean breakAfterAcquireFailure;
    private long timeBetweenConnectErrorMillis;
    private boolean asyncInit;
    private boolean removeAbandoned;
    private long removeAbandonedTimeout;
    private int transactionQueryTimeout;
    private String filters;
    private Properties connectionProperties;

    /**
     * 创建数据源 放入ioc容器中
     *
     * @return
     **/
    @Bean
    public DataSource dataSource() throws SQLException {
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setUrl(this.url);
        dataSource.setUsername(username);
        dataSource.setPassword(password);
        dataSource.setDriverClassName(driverClassName);
        dataSource.setInitialSize(initialSize);
        dataSource.setMaxActive(maxActive);
        dataSource.setMaxWait(maxWait);
        dataSource.setMinIdle(minIdle);
        dataSource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
        dataSource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
        dataSource.setValidationQuery(validationQuery);
        dataSource.setTestWhileIdle(testWhileIdle);
        dataSource.setTestOnBorrow(testOnBorrow);
        dataSource.setTestOnReturn(testOnReturn);
        dataSource.setPoolPreparedStatements(poolPreparedStatements);
        dataSource.setMaxPoolPreparedStatementPerConnectionSize(maxPoolPreparedStatementPerConnectionSize);
        dataSource.setConnectionErrorRetryAttempts(connectionErrorRetryAttempts);
        dataSource.setBreakAfterAcquireFailure(breakAfterAcquireFailure);
        dataSource.setTimeBetweenConnectErrorMillis(timeBetweenConnectErrorMillis);
        dataSource.setAsyncInit(asyncInit);
        dataSource.setRemoveAbandoned(removeAbandoned);
        dataSource.setRemoveAbandoned(removeAbandoned);
        dataSource.setTransactionQueryTimeout(transactionQueryTimeout);
        dataSource.setFilters(filters);
        dataSource.setConnectProperties(connectionProperties);
        return dataSource;
    }

    /**
     * 配置servlet 查看监控页面
     *
     * @param statConfig
     * @return
     **/

    @Bean
    public ServletRegistrationBean druidServlet(StatConfig statConfig) {
        ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(new StatViewServlet(), statConfig.getUrlPattern());
        servletRegistrationBean.addInitParameter("allow", statConfig.getAllow());//白名单
        servletRegistrationBean.addInitParameter("deny", statConfig.getDeny());// 黑名单
        servletRegistrationBean.addInitParameter("loginUsername", statConfig.getLoginUsername());//用户名
        servletRegistrationBean.addInitParameter("loginPassword", statConfig.getLoginPassword());//密码
        servletRegistrationBean.addInitParameter("resetEnable", statConfig.getResetEnable());//是否可以重置数据源
        return servletRegistrationBean;
    }

    /**
     * 获取状态监控配置信息
     */
    @Configuration
    @ConfigurationProperties(prefix = "spring.datasource.stat-view-servlet")
    @Data
    class StatConfig {
        String urlPattern;
        String allow;
        String deny;
        String resetEnable;
        String loginUsername;
        String loginPassword;
    }


    @Bean
    public FilterRegistrationBean filterRegistrationBean(StatFilter statFilter) {
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
        filterRegistrationBean.setFilter(new WebStatFilter());
        filterRegistrationBean.addUrlPatterns(statFilter.urlPattern); // 所有请求进行监控处理
        filterRegistrationBean.addInitParameter("exclusions", statFilter.exclusions);
        filterRegistrationBean.setEnabled(statFilter.enabled);
        return filterRegistrationBean;
    }

    @Configuration
    @ConfigurationProperties(prefix = "spring.datasource.web-stat-filter")
    @Data
    class StatFilter {
        boolean enabled;
        String urlPattern;
        String exclusions;
    }

}
